/**
 * 
 */
package com.nari.heatshare.utils;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.Date;

import com.nari.platform.date.CalendarUtils;

/**
 * 热量表数据、分配表数据的数据平滑处理
 * @author Xiaopeng
 * @date 2013-10-16
 */
public class MeterDataTransitionUtil {

	/**
	 * 计算两个日期之间对应的数值之差，并将其换算成单日数据差值
	 * @param earlyValue 前一次的历史数据
	 * @param earlyDate 前一次历史数据对应的日期
	 * @param lateValue 后一次的历史数据
	 * @param lateDate 后一次历史数据对应的日期
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-10-16
	 */
	public static double calcGradeValueByDay(double earlyValue, Date earlyDate, 
			double lateValue, Date lateDate) throws Exception {
		double perDayGradeValue = 0; //每天的步阶值
		double subtractByDate = new BigDecimal(lateValue)
				.subtract(new BigDecimal(earlyValue))
				.doubleValue();
		//计算两个日期间相差的天数
		int betweenDays = CalendarUtils.calcDaysBetweenDatesPeriod(earlyDate, lateDate);
		if(betweenDays == 0) { //同一天的数据
			//计算两个日期间相差的小时数
			long betweenHours = CalendarUtils.calcHoursBetweenDatesPeriod(earlyDate, lateDate);
			if(betweenHours == 0) { //同一天、同一时的数据
				//计算两个日期间相差的分钟数
				long betweenSeconds = CalendarUtils.calcSecondsBetweenDatesPeriod(earlyDate, lateDate);
				//每天的步阶值
				perDayGradeValue = new BigDecimal(subtractByDate)
						.divide(new BigDecimal(betweenSeconds), new MathContext(5, RoundingMode.HALF_UP))
						.multiply(new BigDecimal(60 * 24))
						.doubleValue();
			} else { //同一天、不同时的数据
				//每天的步阶值
				perDayGradeValue = new BigDecimal(subtractByDate)
						.divide(new BigDecimal(betweenHours), new MathContext(5, RoundingMode.HALF_UP))
						.multiply(new BigDecimal(24))
						.doubleValue();
			}
		} else { //不同天的数据
			//每天的步阶值
			perDayGradeValue = new BigDecimal(subtractByDate)
					.divide(new BigDecimal(betweenDays), new MathContext(5, RoundingMode.HALF_UP))
					.doubleValue();
		}
		return perDayGradeValue;
	}
	
	/**
	 * 根据参考日期、参考数据、平滑日期、每天的步阶值计算平滑日期的平滑数据
	 * @param referenceValue 参考数据
	 * @param referenceDate 参考日期
	 * @param transitionDate 平滑日期
	 * @param perDayGradeValue 每天的步阶值
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-10-16
	 */
	public static double calcTransitionValue(double referenceValue, Date referenceDate, 
			Date transitionDate, double perDayGradeValue) throws Exception {
		double transitionData = 0;
		//计算参考日期与平滑日期相差的天数
		int betweenDays = CalendarUtils.calcDaysBetweenDatesPeriod(referenceDate, transitionDate);
		if(betweenDays == 0) { //同一天的数据
			//计算参考日期与平滑日期相差的小时数
			double betweenHours = CalendarUtils.calcHoursBetweenDatesPeriod(referenceDate, transitionDate);
			if(betweenHours == 0) { //同一天、同一时的数据
				//计算参考日期与平滑日期相差的分钟数
				long betweenSeconds = CalendarUtils.calcSecondsBetweenDatesPeriod(referenceDate, transitionDate);
				//计算每分钟的步阶值
				double perSecondGradeValue = new BigDecimal(perDayGradeValue)
						.divide(new BigDecimal(24 * 60), new MathContext(5, RoundingMode.HALF_UP))
						.doubleValue();
				//计算平滑值
				transitionData = new BigDecimal(perSecondGradeValue)
						.multiply(new BigDecimal(betweenSeconds))
						.add(new BigDecimal(referenceValue))
						.doubleValue();
			} else { //同一天、不同时的数据
				//计算每小时的步阶值
				double perHourGradeValue = new BigDecimal(perDayGradeValue)
					.divide(new BigDecimal(24), new MathContext(5, RoundingMode.HALF_UP))
					.doubleValue();
				//计算平滑值
				transitionData = new BigDecimal(perHourGradeValue)
						.multiply(new BigDecimal(betweenHours))
						.add(new BigDecimal(referenceValue))
						.doubleValue();
			}
		} else { //不同天的数据
			//计算平滑值
			transitionData = new BigDecimal(perDayGradeValue)
					.multiply(new BigDecimal(betweenDays), new MathContext(5, RoundingMode.HALF_UP))
					.add(new BigDecimal(referenceValue))
					.doubleValue();
		}
		return transitionData;
	}
	
}
